/**
 * @brief
 * @details 上位机在下发参数、状态做状态同步时，希望的是将值立马下发到下位机，下位机正确响应，并做出状态变更上传；
**          可是由于通讯时差，导致值已经下发，在等待下位机回复的时间内，状态会出现抖动不稳定；该类设计的目的就是将值锁定一段时间，
**          在锁定时间内，正常设置值无效，屏蔽一段时间内的值设置
 * @author    Yin
 * @version   1.0
 * @date
 * @copyright
 * @note
 */

#ifndef LOCKINGVALUE_H
#define LOCKINGVALUE_H


#include <QObject>
#include <QTime>

template<typename T>
class LockingValue
{
public:

    LockingValue()
    {
        m_lockTime.restart();
        m_lockTimeTick = 0;
    }

    LockingValue(T val)
    {
        m_val = val;
        m_lockTime.restart();
        m_lockTimeTick = 0;
    }

    /**
     * @brief  ~LockingValue 析构函数
     * @return
     */
    virtual ~LockingValue() {}

    /**
     * @brief   == 重载
     * @return  是否相等
     */
    bool operator==(LockingValue& lockingValue) const
    {
        return m_val == lockingValue.getValue();
    }

    /**
     * @brief   setValue 设置值
     * @param   val 基础数据类型
     * @param   isForce 是否忽略锁定时间，并清空锁定计时，强制设置
     * @param   lockTimeTick 锁定时间
     * @return  是否成功设置值
     * @note    锁定期间内且非强制设置则返回false
     */
    bool setValue(const T val, const bool isForce = false, const int lockTimeTick = 0)
    {
        if(!isForce && (m_lockTime.elapsed() < m_lockTimeTick))
            return false;

        this->m_val = val;
        m_lockTimeTick = lockTimeTick;
        if(lockTimeTick > 0)
            m_lockTime.restart();

        return true;
    }

    /**
     * @brief   getValue 获取值
     * @return  值
     */
    T getValue()
    {
        return m_val;
    }

private:
    /**
     * @brief   = 禁止直接拷贝
     */
    LockingValue& operator=(const LockingValue&) = delete;

private:
    /** 值
     */
    T m_val;

    /** 锁定计时器
     */
    QTime m_lockTime;

    /** 锁定时间
     */
    int m_lockTimeTick;
};

#endif // LOCKINGVALUE_H
